/**
    选择文件上传
        根据不分离的后端.html改写的.vue组件

        props
            dialogVisible.sync[boolean = false] 组件是否显示
            initParams[object = {}] 初始化请求的参数
        
        emit
            close(arr) 关闭组件触发
                arr[array = []] 上传的文件聚合
 */

<template>
    <el-dialog title="选择文件"
               :visible.sync="dialogVisible"
               append-to-body
               :before-close="handleClose"
               center
               @open="handleOpen"
               width="1000px">
        <div class="file-main"
             v-loading="loading">
            <el-tabs v-model="activeName"
                     @tab-click="handleClick">
                <el-tab-pane label="拖拽模式"
                             name="dragMode"></el-tab-pane>
                <el-tab-pane label="兼容模式"
                             name="buttonMode"></el-tab-pane>
            </el-tabs>
            <table class="table table-bordered">
                <tr>
                    <td class="td-head">所属目录：</td>
                    <td class="td-body">{{catalogName}}</td>
                </tr>

                <tr>
                    <td class="td-head">当前目录：</td>
                    <td class="td-body">{{customName}}</td>
                </tr>

                <tr>
                    <td class="td-head">允许类型：</td>
                    <td class="td-body"><span style="color: #F56C6C">{{accept | fileExt}}</span></td>
                </tr>

                <tr>
                    <td class="td-head">上传要求：</td>
                    <td class="td-body"><span style="color: #F56C6C">{{fileDesc}}</span></td>
                </tr>

                <tr v-if="archList && archList.length > 0">
                    <td class="td-head">文件引用：</td>
                    <td class="td-body">
                        <el-checkbox-group v-model="archChecked">
                            <div v-for="item in archList"
                                 :key="item.attachId">
                                <el-checkbox :label="item.attachId">{{item.fileName}}</el-checkbox>
                            </div>
                        </el-checkbox-group>
                        <el-button type="primary"
                                   size="small"
                                   @click="addRelated">引用选中的文件</el-button>

                    </td>
                </tr>

                <tr v-if="!dragMode">
                    <td class="td-head">操作：</td>
                    <td class="td-body">
                        <el-upload multiple
                                   :action="urls.upload"
                                   :show-file-list="false"
                                   :with-credentials="true"
                                   :accept="accept"
                                   :data="formData"
                                   :file-list="uploadList"
                                   :headers="headers"
                                   :limit="limit"
                                   :before-upload="beforeUploadFile"
                                   :on-progress="uploadFileProcess"
                                   :on-success="handleFileSuccess"
                                   :on-error="handleError"
                                   :on-exceed="fnExceed">
                            <el-button v-if="!dragMode"
                                       size="mini"
                                       type="primary">选择文件</el-button>
                        </el-upload>
                    </td>
                </tr>

                <tr v-if="!dragMode && pdfSignEnabled">
                    <td class="td-head">签章：</td>
                    <td class="td-body">
                        <el-button type="primary"
                                   @click="signAndUp"
                                   size="mini">签章并上传</el-button>
                    </td>
                </tr>

                <tr>
                    <td class="td-head">上传列表：</td>
                    <td class="td-body"
                        style="padding-bottom: 32px">
                        <div class="list">
                            <el-row v-for="(item,index) in uploadList"
                                    :key="item.uid"
                                    class="underline">
                                <el-col :span="10">
                                    <span><i class="bg"></i>{{item.name | fileName}}</span>
                                </el-col>
                                <el-col :span="8">
                                    <div v-show="item.progressFlag">
                                        <el-progress :percentage="item.progressPercent"></el-progress>
                                    </div>
                                    <div align="center">
                                        <el-link v-show="item.status === 'success'"
                                                 type="success">上传成功</el-link>
                                        <el-link v-show="item.status === 'fail'"
                                                 type="danger"
                                                 @click="showMsg(item.errorMsg)">上传失败!</el-link>
                                    </div>
                                </el-col>
                                <el-col :span="3">
                                    <span>{{item.size | fileSize}}</span>
                                </el-col>
                                <el-col :span="3">
                                    <el-link v-show="item.status === 'success'|| item.status === 'fail'"
                                             type="primary"
                                             @click="removeFile(item,index)">删除</el-link>
                                </el-col>
                            </el-row>
                        </div>
                    </td>
                </tr>

                <tr v-if="dragMode">
                    <td class="td-area"
                        colspan="2">
                        <el-upload class="dragMode"
                                   multiple
                                   drag
                                   :action="urls.upload"
                                   :show-file-list="false"
                                   :with-credentials="true"
                                   :accept="accept"
                                   :data="formData"
                                   :headers="headers"
                                   :file-list="uploadList"
                                   :limit="limit"
                                   :before-upload="beforeUploadFile"
                                   :on-progress="uploadFileProcess"
                                   :on-success="handleFileSuccess"
                                   :on-error="handleError"
                                   :on-exceed="fnExceed">
                            <template v-if="dragMode">
                                <i class="el-icon-upload"></i>
                                <div class="el-upload__text">将文件拖到此处，或<em>点击上传</em></div>
                            </template>
                        </el-upload>
                    </td>
                </tr>
            </table>
            <!-- <div style="height: 100px"
                 v-if="!dragMode"></div>
            <div class="footer">
                <el-button type="danger"
                           @click="close"
                           size="small">关闭</el-button>
            </div> -->
        </div>
        <span slot="footer"
              class="dialog-footer">
            <el-button @click="handleClose">关 闭</el-button>
            <!-- <el-button type="primary"
                       @click="$emit('update:dialogVisible', false)">确 定</el-button> -->
        </span>
    </el-dialog>
</template>

<script>
import request from '@/utils/requestNew.js'
import { getCsrfToken } from "@/utils/auth"

export default {
    props: {
        dialogVisible: {
            type: Boolean,
            default: false
        },
        initParams: {
            type: Object,
            default: () => {
                return {}
            }
        },
        limit: Number
    },
    data () {
        return {
            // 加载中
            loading: false,
            activeName: 'dragMode',
            dragMode: true,
            pdfSignEnabled: false,
            urls: {
                init: '/file/related/getSelectFileModel',
                upload: process.env.VUE_APP_BASE_API + '/file/related/multiUpload',
                deleteFile: '/file/related/deleteFile?attachId=',
                queryArchiving: '/file/archiving/queryArchiving',
                addRelated: '/file/archiving/addRelated'
            },
            //element自动发送的请求不包含CSRF KEY，要自行在表单参数里添加
            headers: {
                'X-CSRF-TOKEN': getCsrfToken(),
                'X-Requested-With': 'X-CSRF-TOKEN'
            },
            formData: {
                dataKey: null,
                businessType: null,
                archItemId: null,
                groupId: null,
                catalogId: null,
                catalogType: null
            },
            accept: '',
            fileDesc: '',
            catalogName: '',
            customName: '',
            uploadList: [],
            archList: [],
            archChecked: [],
            initData: {
                catalog: {}
            }
        }
    },
    created () {

    },
    methods: {
        // 打开弹窗
        handleOpen () {
            // 重置data数据
            Object.assign(this.$data, this.$options.data())

            this.loading = true
            // 获取初始化数据
            this.queryInit().then(() => {
                //初始始化完毕查询归档记录
                this.queryArchiving().finally(() => {
                    this.loading = false
                })
            }).catch(() => {
                this.loading = false
            })
        },
        // 关闭弹窗
        handleClose (done) {
            this.$emit('update:dialogVisible', false)
            this.$emit('close', this.uploadList)
            // done()
        },
        // 获取初始化数据
        queryInit: function () {
            return request({
                url: this.appendUrl(this.urls.init, this.initParams),
                // url: '/file/related/getSelectFileModel?businessType=expert_apply&dataKey=00018a8b-c930-4f72-a9ab-a7adc48e89ab&archItemId=00018a8b-c930-4f72-a9ab-a7adc48e89ab&addItemId=1af00c46-68f2-4d58-ba23-c588840152fa&groupId=691b6e334ae824ae8f51065cf0615ae4&catalogId=002.001.001&catalogType=project&addItemId=1af00c46-68f2-4d58-ba23-c588840152fa',
                // data: {
                //     businessType: 'expert_apply',
                //     dataKey: '00018a8b-c930-4f72-a9ab-a7adc48e89ab',
                //     archItemId: '00018a8b-c930-4f72-a9ab-a7adc48e89ab',
                //     addItemId: '1af00c46-68f2-4d58-ba23-c588840152fa',
                //     groupId: '691b6e334ae824ae8f51065cf0615ae4',
                //     catalogId: '002.001.001',
                //     catalogType: 'project',
                //     addItemId: '1af00c46-68f2-4d58-ba23-c588840152fa'
                // },
                data: this.initParams
            }).then(r => {
                this.initData = r.parameters

                let res = r.parameters

                this.formData = {
                    dataKey: res.dataKey || null,
                    businessType: res.businessType || null,
                    archItemId: res.archItemId || null,
                    groupId: res.groupId || null,
                    catalogId: res.catalog.catalogId || null,
                    catalogType: res.catalogType || null
                }

                this.pdfSignEnabled = (res.pdfSignEnabled === 'true')
                this.accept = res.catalog.fileTypeExts || ''
                this.fileDesc = res.groupItem.uploadInfo || ''
                this.catalogName = res.catalog.fullName || res.catalog.catalogName || ''
                this.customName = res.groupItem.customName || res.groupItem.catalogName || ''
            })
        },
        //上传的前置动作，返回false将取消上传
        beforeUploadFile: function beforeUploadFile (file) {
            //这里要验证文件类型及大小
            var fileInfo = {
                uid: file.uid,
                name: file.name,
                size: file.size,
                type: file.type,
                progressFlag: true,
                progressPercent: 0,
                status: '',
                errorMsg: ''
            };
            if (this.accept && file.name && file.name.indexOf(".") >= 0) {
                var array = this.accept.split(",");
                var fileExtension = file.name.substring(file.name.lastIndexOf('.'));
                if (!array.includes(fileExtension)) {
                    this.$message.error('存在与上传类型不符合的文件，已检查')
                    return false;
                }
            }
            this.uploadList.push(fileInfo);
        },
        //处理上传过程
        uploadFileProcess: function uploadFileProcess (event, file) {
            this.uploadList.forEach(function (item) {
                if (item.uid === file.uid) {
                    item.progressPercent = Math.floor(file.percentage || 0);
                }
            });
        },
        //处理上传成功时的动作
        handleFileSuccess: function handleFileSuccess (res, file) {
            this.uploadList.forEach(function (item) {
                if (item.uid === file.uid) {
                    item.progressFlag = false;
                    if (res.success === true) {
                        item.status = 'success';
                        item.attachId = res.parameters.attachId;
                        item.relatedId = res.parameters.relatedId;
                    } else {
                        item.status = 'fail';
                        item.errorMsg = res.message || '未知错误';
                    }
                }
            });
        },
        //处理上传异常
        handleError: function handleError (err, file) {
            this.uploadList.forEach(function (item) {
                if (item.uid === file.uid) {
                    item.status = 'fail';
                    item.progressFlag = false;
                }
            });
            this.$message.error('文件上传失败，详情请查看日志')
        },
        //删除文件(基于文件列表的数据进行操作)
        removeFile: function removeFile (item, index) {
            var _this = this;
            if (item.status !== 'success' || !item.attachId) {
                this.uploadList.splice(index, 1);
                return;
            }
            this.$confirm('真的要删除吗?', '提示', {
                confirmButtonText: '删除',
                cancelButtonText: '取消',
                type: 'warning'
            }).then(() => {
                // let loading = this.$loading()
                this.loading = true
                request({
                    url: _this.urls.deleteFile + item.attachId
                }).then(res => {
                    if (res && res.success) {
                        _this.$message.success('删除成功')
                        _this.uploadList.splice(index, 1);
                    } else {
                        res = res || {};
                        this.$message.error(res.message || "删除失败")
                    }
                }).finally(() => {
                    // loading.close()
                    this.loading = false
                })
            }).catch(() => { })
        },
        showMsg: function showMsg (errorMsg) {
            this.$message.error(errorMsg)
        },
        // close: function close () {
        //     jQuery.dialogReturnValue(false);
        //     if (this.uploadList && this.uploadList.length > 0) {
        //         jQuery.dialogReturnValue(this.uploadList);
        //     }
        //     jQuery.fn.dialogClose();
        // },
        handleClick: function handleClick (tab) {
            this.dragMode = tab.name === 'dragMode';
        },
        //查询本目录下是否存在归档的文件，如果有就显示出来提供引用
        queryArchiving: function queryArchiving () {
            var _this = this;
            var url = this.urls.queryArchiving;
            url += "?dataKey=" + this.initData.dataKey;
            url += "&catalogId=" + this.initData.catalog.catalogId;
            // $.get(url, function (res) {
            //     if (res && res.length > 0) {
            //         _this.archChecked = [];
            //         _this.archList = res;
            //     }
            // });
            return request({
                url,
                method: 'get'
            }).then(res => {
                if (res && res.length > 0) {
                    _this.archChecked = [];
                    _this.archList = res;
                }
            })
        },
        //引用选中的归档文件，直接在后台添加关联关系
        addRelated: function addRelated () {
            if (!this.archChecked || this.archChecked.length < 1) {
                this.$message.error("请选择要引用的文件")
            }
            var param = {
                businessType: this.initData.businessType,
                dataKey: this.initData.dataKey,
                groupId: this.initData.groupId,
                catalogId: this.initData.catalog.catalogId,
                attachId: this.archChecked
            };
            // $.postJson(this.urls.addRelated, param, function (res) {
            //     if (res && res.success) {
            //         $.msg.success("保存成功");
            //         setTimeout(function () {
            //             jQuery.dialogReturnValue(param);
            //             jQuery.fn.dialogClose();
            //         }, 800);
            //     } else {
            //         $.msg.error(res.message || "保存失败");
            //     }
            // });
            request({
                url: this.urls.addRelated,
                data: param
            }).then(res => {
                if (res && res.success) {
                    this.$message.success("保存成功")
                    setTimeout(() => {
                        this.handleClose()
                    }, 800);
                } else {
                    this.$message.error(res.message || "保存失败")
                }
            })
        },
        signAndUp: function () {
            var formData = {
                dataKey: this.initData.dataKey || null,
                businessType: this.initData.businessType || null,
                archItemId: this.initData.archItemId || null,
                addItemId: this.initData.addItemId || null,
                groupId: this.initData.groupId || null,
                catalogId: this.initData.catalog.catalogId || null,
                catalogType: this.initData.catalogType || null
            };
            window.open(this.appendUrl("/file/seal/sign", formData));
        },
        appendUrl: function (url, map) {
            if (!url || !map) {
                return url;
            }
            Object.keys(map).forEach(function (key) {
                var join = url.indexOf("?") == -1 ? "?" : "&";
                url += join + key + "=" + encodeURI(map[key] || '');
            });
            return url;
        },
        // 文件超出个数限制
        fnExceed () {
            this.$message.warning(`最多上传 ${this.limit} 个文件。`)
        }
    },
    filters: {
        fileExt: function (value) {
            if (!value || value.length < 1) return '';
            value = value.replace(/\./g, '');
            return value ? value.replace(/,/g, ' | ') : '';
        },
        fileName: function (value) {
            if (!value || value.length < 1) return '';
            var len = value.length;
            if (len > 20) {
                return value.substring(0, 10) + "..." + value.substring(len - 10, len);
            }
            return value;
        }
    }
}
</script>

<style lang="scss" scoped>
.file-main {
    width: 100%;
    padding: 0 15px;
    box-sizing: border-box;

    .underline {
        padding-top: 10px;
        height: 32px;
        border-bottom: 1px solid #eceff6;
    }
    .table-bordered,
    .table-bordered > tbody > tr > td,
    .table-bordered > tbody > tr > th,
    .table-bordered > tfoot > tr > td,
    .table-bordered > tfoot > tr > th,
    .table-bordered > thead > tr > td,
    .table-bordered > thead > tr > th {
        border: 1px solid #e7ecf1;
    }
    .table {
        width: 100%;
        margin-bottom: 20px;
        border-collapse: collapse;
        border-spacing: 0;
    }
    .thead > tr > th {
        height: 32px;
        background-color: rgb(244, 244, 245);
    }
    .tbody > tr > td {
        height: 32px;
    }
    .td-head {
        width: 20%;
        height: 32px;
        background-color: rgb(244, 244, 245);
        text-align: right;
        padding-right: 20px;
        font-weight: bold;
    }
    .td-body {
        width: 80%;
        padding-left: 20px;
    }
    .td-area {
        border: none;
    }
    .dragMode {
        ::v-deep.el-upload {
            display: block;
            width: 100%;

            .el-upload-dragger {
                width: 100%;
            }
        }
    }
}
</style>
